/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package entities;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Objects;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.Future;
import javax.validation.constraints.NotNull;

/**
 *
 * @author Alberto, Alessandra
 */
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type",discriminatorType = DiscriminatorType.STRING)
@NamedQueries({
    @NamedQuery(
            name = "findAllEvents",
            query = "SELECT e FROM Event e"
    ),
    @NamedQuery(
            name = "removeEvent",
            query = "DELETE FROM Event e WHERE e.id = :Eid"
    ),
})
public abstract class Event implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected Integer id;
    
    @NotNull(message = "May not be empty")
    protected String name;
    
    @NotNull(message = "May not be empty")
    protected Boolean visibility;
    
    @NotNull(message = "May not be empty")
    protected Integer starthour;
    
    @NotNull(message = "May not be empty")
    protected Integer startminute;
    
    @NotNull(message = "May not be empty")
    protected Integer endhour;
    
    @NotNull(message = "May not be empty")
    protected Integer endminute;
    
    @NotNull(message = "Select a date")
    //@Future
    @Temporal(TemporalType.DATE)
    protected Date date;
    
    protected String description;
    
    @ManyToOne
    @JoinColumn(name = "idcreator", referencedColumnName = "id")
    protected User creator;
    
    @ManyToOne
    @JoinColumn(name = "idplace", referencedColumnName = "id")
    protected Place place;
    
    @OneToMany(mappedBy = "event")
    protected Collection<ChangeNotification> changenotifications;
    
    @OneToMany(mappedBy = "event")
    protected Collection<DeleteNotification> deletenotifications;
    
    @OneToMany(mappedBy = "event")
    protected Collection<Invitation> invitations;
    
    @ManyToMany(mappedBy = "events")
    protected Collection<User> participants;
    
    public Event () {
        
    }

    public Event(String name, Boolean visibility, Integer starthour, Integer startminute, Integer endhour, Integer endminute, Date date, String description, User creator, Place place) {
        this.name = name;
        this.visibility = visibility;
        this.starthour = starthour;
        this.startminute = startminute;
        this.endhour = endhour;
        this.endminute = endminute;
        this.date = date;
        this.description = description;
        this.creator = creator;
        this.place = place;
        this.changenotifications = new ArrayList<ChangeNotification>();
        this.deletenotifications = new ArrayList<DeleteNotification>();
        this.invitations = new ArrayList<Invitation>();
        this.participants = new ArrayList<User>();
        this.participants.add(creator);
    }

    public Collection<ChangeNotification> getChangenotifications() {
        return changenotifications;
    }

    public void setChangenotifications(Collection<ChangeNotification> changenotifications) {
        this.changenotifications = changenotifications;
    }

    public Collection<DeleteNotification> getDeletenotifications() {
        return deletenotifications;
    }

    public void setDeletenotifications(Collection<DeleteNotification> deletenotifications) {
        this.deletenotifications = deletenotifications;
    }

    public Collection<Invitation> getInvitations() {
        return invitations;
    }

    public void setInvitations(Collection<Invitation> invitations) {
        this.invitations = invitations;
    }

    public Collection<User> getParticipants() {
        return participants;
    }

    public void setParticipants(Collection<User> participants) {
        this.participants = participants;
    }

    public User getCreator() {
        return creator;
    }

    public void setCreator(User creator) {
        this.creator = creator;
    }

    public Place getPlace() {
        return place;
    }

    public void setPlace(Place place) {
        this.place = place;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Boolean getVisibility() {
        return visibility;
    }

    public void setVisibility(Boolean visibility) {
        this.visibility = visibility;
    }

    public Integer getStarthour() {
        return starthour;
    }

    public void setStarthour(Integer starthour) {
        this.starthour = starthour;
    }

    public Integer getStartminute() {
        return startminute;
    }

    public void setStartminute(Integer startminute) {
        this.startminute = startminute;
    }

    public Integer getEndhour() {
        return endhour;
    }

    public void setEndhour(Integer endhour) {
        this.endhour = endhour;
    }

    public Integer getEndminute() {
        return endminute;
    }

    public void setEndminute(Integer endminute) {
        this.endminute = endminute;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    
    public Date getStartTime () {
        GregorianCalendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, starthour);
        cal.set(Calendar.MINUTE, startminute);
        return cal.getTime();
    }
    
    public void setStartTime (Date date) {
        GregorianCalendar cal = new GregorianCalendar();
        cal.setTime(date);
        starthour = cal.get(Calendar.HOUR_OF_DAY);
        startminute = cal.get(Calendar.MINUTE);
    }
    
    public Date getEndTime () {
        GregorianCalendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, endhour);
        cal.set(Calendar.MINUTE, endminute);
        return cal.getTime();
    }
    
    public void setEndTime (Date date) {
        GregorianCalendar cal = new GregorianCalendar();
        cal.setTime(date);
        endhour = cal.get(Calendar.HOUR_OF_DAY);
        endminute = cal.get(Calendar.MINUTE);
    }
    
    public void addParticipant (User user) {
        this.participants.add(user);
    }
    
    public void removeParticipant (User user) {
        this.participants.remove(user);
    }
    
    public void addInvitation (Invitation invitation) {
        this.invitations.add(invitation);
    }
    
    public void removeInvitation (Invitation invitation) {
        this.invitations.remove(invitation);
    }
    
    public void addChangeNotification (ChangeNotification notification) {
        this.changenotifications.add(notification);
    }
    
    public void removeChangeNotification (ChangeNotification notification) {
        this.changenotifications.remove(notification);
    }
    
    public void addDeleteNotification (DeleteNotification notification) {
        this.deletenotifications.add(notification);
    }
    
    public void removeDeleteNotification (DeleteNotification notification) {
        this.deletenotifications.remove(notification);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Event other = (Event) obj;
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        return true;
    }
    
    
    
}
